home *** CD-ROM | disk | FTP | other *** search
/ MacWorld Secrets (4th Edition) / Mac Secrets CD 4th Ed.toast / Apple Advanced Technologies / Apple Speech Technologies 1.5 / PlainTalk Developer Info / Speech Recognition Manager SDK / SR Sample Code / Speakable Items Example / Sources / Process & Finder Stuff / ProcessUtils.c < prev    next >
Text File  |  1995-06-07  |  10KB  |  308 lines

  1. /*****************************************************************************
  2.  *
  3.  *  ProcessUtils.c
  4.  *
  5.  *  DESCRIPTION
  6.  *        Utiltiy routines for finding and manipulating processes.
  7.  *
  8.  *  AUTHOR:     Matt Pallakoff
  9.  * 
  10.  *  CREATED:     9-9-91
  11.  *
  12.  *****************************************************************************/
  13.  
  14. #include "ProcessUtils.h"
  15.  
  16. OSErr PUFindApp (ResType signature, FSSpec *aFSSpec);
  17. OSErr PULaunchApp (FSSpec *aFSSpec);
  18. OSErr PULaunchAppWithSignature (ResType serviceSignature);
  19.  
  20. void ClearEvenSizeBlock(void *loc, Size len);
  21.  
  22. /****************************************************************************/
  23.  
  24. void ClearEvenSizeBlock(void *loc, Size len)
  25. {
  26.     short *sPtr = loc;
  27.     short    sz = len>>1;
  28.     for (sz = (len>>1)-1; sz >= 0; sz--);
  29.         *sPtr++ = 0;
  30. }
  31.  
  32. /****************************************************************************/
  33.  
  34.  
  35. OSErr PUFindApp (ResType signature, FSSpec *aFSSpec)
  36. {
  37.     DTPBRec                aDTPBRec;
  38.     short                dtRefNum, volRefNum;
  39.     OSErr                err, err2, volErr;
  40.     short                i;
  41.     Str255                name;
  42.     HParamBlockRec        volPB;
  43.     
  44.     err = -1;    /* representing 'not found' */
  45.                                                                     /* For each mounted volume...     */
  46.     i = 0;
  47.     volErr = noErr;
  48.     while ((volErr == noErr) && (err != noErr)) {
  49.         ++i;
  50.                     
  51.                                                                     /* Get Volume information.         */
  52.         volPB.ioParam.ioCompletion = nil;
  53.         volPB.ioParam.ioNamePtr = name;
  54.         volPB.volumeParam.ioVolIndex = i;
  55.         volErr = PBHGetVInfo(&volPB, false);
  56.  
  57.         if (!volErr) {
  58.             volRefNum = volPB.volumeParam.ioVRefNum;
  59.             aDTPBRec.ioNamePtr = name;
  60.             aDTPBRec.ioVRefNum = volRefNum;
  61.                                                                     /* Get Desktop File Database reference for the volume. */
  62.  
  63.             err2 = PBDTGetPath(&aDTPBRec);
  64.             if (!err2) {
  65.                 dtRefNum = aDTPBRec.ioDTRefNum;
  66.                 aDTPBRec.ioCompletion = nil;
  67.                 aDTPBRec.ioNamePtr = name;
  68.                 aDTPBRec.ioDTRefNum = dtRefNum;
  69.                 aDTPBRec.ioIndex = 0; /* Find most recent. */
  70.                 aDTPBRec.ioFileCreator = signature;
  71.                 err = PBDTGetAPPL(&aDTPBRec, false);                /* Search the desktop database for the application. */
  72.                                                                     /* If found, return FSSpec specifying where it is.    */
  73.                 if (!err)
  74.                     err = FSMakeFSSpec(volRefNum,aDTPBRec.ioAPPLParID,aDTPBRec.ioNamePtr,aFSSpec); 
  75.             }
  76.         }
  77.     } /* while */
  78.     
  79.     return err;
  80. }
  81.  
  82. /****************************************************************************/
  83.  
  84.  
  85. /*
  86.  * PULaunchApp launches the application corresponding to the given fsspec.
  87.  */
  88. OSErr PULaunchApp (FSSpec *aFSSpec)
  89. {
  90.     OSErr                    err;
  91.     LaunchParamBlockRec        myLaunchParams;
  92.     
  93.     myLaunchParams.launchBlockID = extendedBlock;
  94.     myLaunchParams.launchEPBLength = extendedBlockLen;
  95.     myLaunchParams.launchFileFlags = 0;
  96.     myLaunchParams.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
  97.     myLaunchParams.launchAppSpec = aFSSpec;
  98.     myLaunchParams.launchAppParameters = nil;
  99.     err = LaunchApplication(&myLaunchParams);
  100.  
  101.     return err;
  102. }
  103.  
  104. /****************************************************************************/
  105.  
  106.  
  107. /* PULaunchAppWithSignature looks for an application with the given signature
  108.  *    on a mounted volume and if it finds it tries to launch it.  If all goes well,
  109.  *    noErr is returned.  If the app couldn't be found or launched then a non-noErr
  110.  *    value is returned.
  111.  */            
  112.  
  113.  
  114. OSErr PULaunchAppWithSignature (ResType serviceSignature)
  115. {
  116.  
  117.     FSSpec    aFSSpec;
  118.     OSErr    err;
  119.  
  120.     err = PUFindApp(serviceSignature, &aFSSpec);
  121.  
  122.     if (!err)
  123.         err = PULaunchApp(&aFSSpec);
  124.  
  125.     return err;
  126. }
  127.  
  128. /****************************************************************************/
  129.  
  130.  
  131. OSErr PUFindLocalProcess (OSType processSignature,
  132.                             Boolean launchIfCan,
  133.                             LocationNameRec *theLocation,
  134.                             PortInfoRec *thePortInfo)
  135. {
  136.     PPCPortRec            myPortName;
  137.     PortInfoRec            myPortInfo;
  138.     Boolean                found = false;
  139.     short                index = 0;
  140.     IPCListPortsPBPtr    thePB = (IPCListPortsPBPtr)NewPtrClear(sizeof(IPCListPortsPBRec));
  141.     OSErr                err = MemError();
  142.     
  143.     
  144.         /* Exit immedieately if couldn't allocte param block.    */
  145.     if (err)
  146.         return err;
  147.     
  148.     
  149.         /* Check local machine for process with given signature.    */
  150.  
  151.                                         /*    Match any port.  We could match just ports with given signature and a given type,
  152.                                          *        but then we'd either have to assume the system always gives applications a type
  153.                                          *        of 'ep10' (which might not be true in the future) or we'd have to have services
  154.                                          *        explicitly open their ports using PPCOpenPort, providing their type (which will
  155.                                          *        usually by 'APPL'.  It's easier just to look through all available local ports, looking
  156.                                          *        for a port with creator equal to the processSignature we're looking for.
  157.                                          *    We could also use the serviceName to determine the port, but then if we decided to
  158.                                          *        change the name of a service (e.g. "DECTalk Service" to "Talker Server") then
  159.                                          *        we'd have to recompile E.T.  One is much less likely to change the services type.
  160.                                          */
  161.     while ((!err) && (!found)) {
  162.         myPortName.nameScript = 0;
  163.         myPortName.name[1] = '=';
  164.         myPortName.name[0] = 1;
  165.         myPortName.portKindSelector = ppcByString;
  166.         myPortName.u.portTypeStr[1] = '=';
  167.         myPortName.u.portTypeStr[0] = 1;
  168.         
  169.         thePB->ioCompletion = nil;
  170.         thePB->startIndex = index;
  171.         thePB->requestCount = 1;
  172.         thePB->portName = &myPortName;
  173.         thePB->locationName = nil;
  174.         thePB->bufferPtr = &myPortInfo;
  175.         
  176.         err = IPCListPorts(thePB, FALSE);
  177.         if (!err)
  178.             if (thePB->actualCount <= 0)
  179.                 err = PROCESS_NOT_FOUND_ERR;                    /* Return PROCESS_NOT_FOUND_ERR if port not found.    */
  180.             else
  181.                 found = (((myPortName.portKindSelector == ppcByCreatorAndType) && (myPortInfo.name.u.port.portCreator == processSignature)) ||
  182.                          ((myPortName.portKindSelector == ppcByString) && (*(OSType *)(myPortInfo.name.u.portTypeStr + 1) == processSignature)));
  183.             
  184.         ++index;                
  185.     }
  186.  
  187.         /* Cleanup.    */
  188.     DisposPtr((Ptr)thePB);
  189.  
  190.  
  191.         /* If we found the correct service process, return its location and name. */
  192.     if (found) {
  193.         ClearEvenSizeBlock(theLocation, sizeof(LocationNameRec));    /* Clear location means local machine. */
  194.         BlockMove((Ptr)&myPortInfo, (Ptr)thePortInfo, sizeof(PortInfoRec));
  195.         err = noErr;
  196.     }
  197.     
  198.     
  199.         /* Couldn't find running process.  See if can find app on mounted volume and launch it.    */
  200.     if ((!found) && (launchIfCan)) {
  201.             /* Try to launch application. */
  202.         err = PULaunchAppWithSignature(processSignature);
  203.  
  204.             /* Call PUFindLocalProcess again to get location of newly launched app. */
  205.         if (!err)
  206.             err = PUFindLocalProcess(processSignature, false, theLocation, thePortInfo);
  207.  
  208.         found = (!err);
  209.     }
  210.         
  211.     return err;
  212. }
  213.  
  214. /*****************************************************************************************/
  215.  
  216. OSErr PUSendAppleEventWith2Params(long            sessionID,
  217.                             OSType            signature,
  218.                             LocationNameRec    *theLocation, 
  219.                             PortInfoRec        *thePortInfo, 
  220.                             AEEventClass    eventClass,
  221.                             AEEventID        eventID,
  222.                             AEKeyword        keyWord1,
  223.                             DescType        dataType1, 
  224.                             void            *dataPtr1, 
  225.                             Size            dataSize1,
  226.                             AEKeyword        keyWord2,
  227.                             DescType        dataType2, 
  228.                             void            *dataPtr2, 
  229.                             Size            dataSize2,
  230.                             Boolean            waitForReply,
  231.                             long            timeOut,
  232.                             AppleEvent        *theReply)
  233. {
  234.     OSErr            err,err2;
  235.     TargetID        theTargetID;
  236.     AppleEvent        theAevt;
  237.     AEAddressDesc    theTarget;
  238.     AESendMode        sendMode;
  239.  
  240.     if (sessionID != 0) {
  241.             err = AECreateDesc(typeSessionID, (Ptr) &sessionID, (Size)sizeof(sessionID), &theTarget);
  242.     } else if ((long)signature != 0) {
  243.             err = AECreateDesc(typeApplSignature, (Ptr) &signature, (Size)sizeof(signature), &theTarget);
  244.     } else {
  245.         theTargetID.location = *theLocation;
  246.         theTargetID.name = thePortInfo->name;
  247.         err = AECreateDesc(typeTargetID, (Ptr) &theTargetID, (Size)sizeof(theTargetID), &theTarget);
  248.     }
  249.     
  250.     if (err == noErr) 
  251.         err = AECreateAppleEvent(eventClass, eventID, &theTarget, kAutoGenerateReturnID, kAnyTransactionID, &theAevt);
  252.  
  253.     if ((err == noErr) && (dataPtr1 != 0))
  254.         err = AEPutParamPtr(&theAevt, keyWord1, dataType1, (Ptr) dataPtr1, dataSize1);
  255.  
  256.     if ((err == noErr) && (dataPtr2 != 0))
  257.         err = AEPutParamPtr(&theAevt, keyWord2, dataType2, (Ptr) dataPtr2, dataSize2);
  258.  
  259.     if (waitForReply)
  260.         sendMode = kAEWaitReply;
  261.     else
  262.         sendMode = kAENoReply;
  263.         
  264.     if (err == noErr)
  265.         err = AESend(&theAevt, theReply, sendMode, kAENormalPriority, timeOut, (AEIdleUPP)0, (AEFilterUPP)0);
  266.  
  267.         /* Get rid of structures    */
  268.     err2 = AEDisposeDesc(&theAevt);
  269.     err2 = AEDisposeDesc(&theTarget);
  270.  
  271.     return(err);
  272. }
  273.  
  274. /*****************************************************************************************/
  275.  
  276. OSErr PUSendAppleEventWith1Param(LocationNameRec    *theLocation, 
  277.                             PortInfoRec        *thePortInfo, 
  278.                             AEEventClass    eventClass,
  279.                             AEEventID        eventID,
  280.                             DescType        dataType, 
  281.                             void            *dataPtr, 
  282.                             Size            dataSize)
  283. {
  284.     return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
  285.                             keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
  286.                             false, 0, NULL);
  287. }
  288.  
  289. /*****************************************************************************************/
  290.  
  291. OSErr PUSendAppleEventWith1ParamAndWait(LocationNameRec    *theLocation, 
  292.                             PortInfoRec        *thePortInfo, 
  293.                             AEEventClass    eventClass,
  294.                             AEEventID        eventID,
  295.                             DescType        dataType, 
  296.                             void            *dataPtr, 
  297.                             Size            dataSize,
  298.                             long            timeout,
  299.                             AppleEvent        *theReply)
  300. {
  301.     return PUSendAppleEventWith2Params(0, (OSType)0, theLocation, thePortInfo, eventClass, eventID,
  302.                             keyDirectObject, dataType, dataPtr, dataSize, keyDirectObject, (DescType)0,nil,(Size)0,
  303.                             true, timeout, theReply);
  304.  
  305. }
  306.  
  307. /*****************************************************************************************/
  308.